/**
	******************************************************************************
	* File Name					: main.c
	* Date							 : 30/10/2014 20:02:37
	* Description				: Main program body
	******************************************************************************
	*
	* COPYRIGHT(c) 2014 STMicroelectronics
	*
	* Redistribution and use in source and binary forms, with or without modification,
	* are permitted provided that the following conditions are met:
	*	 1. Redistributions of source code must retain the above copyright notice,
	*			this list of conditions and the following disclaimer.
	*	 2. Redistributions in binary form must reproduce the above copyright notice,
	*			this list of conditions and the following disclaimer in the documentation
	*			and/or other materials provided with the distribution.
	*	 3. Neither the name of STMicroelectronics nor the names of its contributors
	*			may be used to endorse or promote products derived from this software
	*			without specific prior written permission.
	*
	* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
	* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
	* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
	* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
	* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
	* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
	* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
	*
	******************************************************************************
	*/

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "ff.h"
#include "ff_gen_drv.h"
#include "sdram_diskio.h" /* defines SDRAMDISK_Driver as external */
#include "sd_diskio.h" /* defines SD_Driver as external */
#include "exflash_diskio.h" /* defines Exflash_Driver as external */
#include "usb_device.h"
#include "dataflash.h"
#include "misc.h"
#define MT1Addr 0x5D
#define MT2Addr 0x48

#define MPUAddr 0x68

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;

DAC_HandleTypeDef hdac;

DCMI_HandleTypeDef hdcmi;

I2C_HandleTypeDef hi2c2;

SD_HandleTypeDef hsd;
HAL_SD_CardInfoTypedef SDCardInfo;

SPI_HandleTypeDef hspi5;

UART_HandleTypeDef huart4;

SDRAM_HandleTypeDef hsdram1;
FMC_SDRAM_CommandTypeDef sdramCommand;

uint8_t SDRAMDISK_DriverNum;			/* FatFS SDRAMDISK part */
char SDRAMDISK_Path[4];					 /* SDRAMDISK logical drive path */
uint8_t SD_DriverNum;			/* FatFS SD part */
char SD_Path[4];					 /* SD logical drive path */
uint8_t ExFlash_DriverNum;			/* FatFS ExFlash part */
char ExFlash_Path[4];					 /* ExFlash logical drive path */
extern Diskio_drvTypeDef	ExFlash_Driver;

static FATFS fatfs;
//static FATFS sdramfs;
/* USER CODE BEGIN 0 */

	/*	目前公认的标准是，存储体中电容的数据有效保存期上限是64ms（毫秒，1/1000秒），
	 *	也就是说每一行刷新的循环周期是64ms。这样刷新速度就是：行数量/64ms。我们在看内
	 *	存规格时，经常会看到4096 Refresh Cycles/64ms或8192 RefreshCycles/64ms的标识，
	 *	这里的4096与8192就代表这个芯片中每个L-Bank的行数。刷新命令一次对一行有效，
	 *	发送间隔也是随总行数而变化，4096行时为15.625μs（微秒，1/1000毫秒），
	 *	8192行时就为7.8125μs。使用 (15.62 us x Freq) - 20 求得
	 */
//#define REFRESH_COUNT			 ((uint32_t)0x027C)	 /* SDRAM refresh counter 8192 (84Mhz SD clock) */
#define REFRESH_COUNT			 ((uint32_t)0x050C)	 /* SDRAM refresh counter 4096 (84Mhz SD clock) */


#define BSP_LED1_OFF() 		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET)
#define BSP_LED2_OFF() 		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET)
#define BSP_LED1_ON() 		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET)
#define BSP_LED2_ON() 		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET)
#define BSP_LED1_TOGGLE() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET)
#define BSP_LED2_TOGGLE() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET)
/* USER CODE END 0 */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_ADC2_Init(void);
static void MX_DAC_Init(void);
static void MX_DCMI_Init(void);
static void MX_FMC_Init(void);
static void MX_I2C2_Init(void);
static void MX_SDIO_SD_Init(void);
static void MX_SPI5_Init(void);
static void MX_UART4_Init(void);
static void SDRAM_Initialization_Sequence(FMC_SDRAM_CommandTypeDef *Command);

void Debug(char *msg);
void uartWrite(void *msg);
void i2cWrite(uint8_t I2C_ADDRESS, uint8_t *aTxBuffer, uint8_t TXBUFFERSIZE);
void i2cRead(uint8_t I2C_ADDRESS, uint8_t RegAddr, uint8_t *aRxBuffer, uint8_t RXBUFFERSIZE);
/* Start ----------------------------------*/
int main(void)
{

	/* MCU Configuration----------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* Configure the system clock */
	SystemClock_Config();

	/* System interrupt init*/
	/* Sets the priority grouping field */
	HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
	HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_ADC1_Init();
	MX_ADC2_Init();
	MX_DAC_Init();
	MX_DCMI_Init();

	
	MX_SDIO_SD_Init();
	MX_SPI5_Init();
	MX_UART4_Init();
	MX_USB_DEVICE_Init();
	MX_FMC_Init();
 	MX_I2C2_Init();
	/*## FatFS: Link the SDRAMDISK disk I/O driver ###############################*/
	ExFlash_DriverNum = FATFS_LinkDriver(&ExFlash_Driver, ExFlash_Path);
	/*## FatFS: Link the SD disk I/O driver ###############################*/
	SD_DriverNum = FATFS_LinkDriver(&SD_Driver, SD_Path);
	
#if 0
	FRESULT res = f_mount(&fatfs,SD_Path,1);
	
	if (res == FR_OK) {
		FRESULT res2 = f_chdrive(SD_Path);
		if(res2 == FR_OK)	
		{
			Debug("Change Drive Done!");
			writeTFCard(&fatfs,SD_Path);
		}
	}else{
		char errmsg[30];
		sprintf(errmsg,"Fail to mount SD. Error Code is %d",res);
		Debug(errmsg);
	}
#endif
	
#if 0
	FATFS fatfs_exflash;
	FRESULT res3 = f_mount(&fatfs_exflash,ExFlash_Path,1);
	
	if (res3 == FR_OK) {
		Debug("ExFlash Mounted!");
	}else{
		char errmsg[30];
		sprintf(errmsg,"Fail to mount ExFlash. Error Code is %d",res3);
		Debug(errmsg);
	}
#endif
	/* USER CODE BEGIN 3 */
	//writeTFCard(SD_Path);
	//HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_2);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);

	// Enable MAX3372E (disable three_state pin)
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET);
	// Disable C2
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);			//as PIN_RESET HSYC is 2.85
	// Enable C1
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);		//as PIN_RESET CLK is 1.54


#if 0	//Done
	testExFlash();
	writeExFlash();
#endif

#if 1
	//SDRAM Write Data
	#define BUFFER_SIZE  15
	uint32_t writeBuffer[BUFFER_SIZE] = {0x01,0x02,0xbb,0x73,0x68, \
																			 0x65,0x6c,0x6c,0x3a,0x2f, \
																			 0x64,0x61,0x74,0x61,0x2f};
	uint32_t addr = SDRAM_DEVICE_ADDR;
	BSP_SDRAM_WriteData(&addr,writeBuffer,15);
	
	uint32_t readBuffer[BUFFER_SIZE];
	memset(readBuffer,0,BUFFER_SIZE);
	//SDRAM Read Data
	BSP_SDRAM_ReadData(&addr,readBuffer,BUFFER_SIZE);

	char debugmsg[100];
	sprintf(debugmsg,"SDRAM read data:");
	char numbers[100];
	memset(numbers,0,100);
	char part[10];
	for(int i = 0;i< BUFFER_SIZE;i++)
	{
		memset(part,0,10);
		sprintf(part,"%02x,",readBuffer[i]);
		sprintf(numbers,"%s%s",numbers,part);
	}
	sprintf(debugmsg,"%s %s",debugmsg,numbers);
	Debug(debugmsg);
#endif
	
	//read MPU 0x75 data should be 0x143A
//	uint8_t data[1] = {0x00};
//	i2cRead(MPUAddr,0x75,data,1);
//	uartWrite(data);
	Debug("UART");
	
	uint8_t mt_data[2] = {0x00,0x00};
	i2cRead(MT2Addr,0xFF,mt_data,2);
	char mtmsg[20];
	sprintf(mtmsg,"mt chip version is %02x%02x",mt_data[0],mt_data[1]);
	Debug(mtmsg);
//	uint8_t RegAddr = 0x00;
//	HAL_I2C_Master_Transmit(&hi2c2, (uint16_t)0xBA, &RegAddr, 1, (uint32_t)DEFTIMEOUT);
//	HAL_I2C_Master_Receive(&hi2c2, (uint16_t)0xBA, mt_data, 2, (uint32_t)DEFTIMEOUT);
//	uartWrite(mt_data);
	// Setting C1
	// Read Camera	DCMI file1
	 // Enable SDCard
	// Write to SDCard						// Or write to SDRAM first then write to sdcard
	// When Finished
		// File process
		// Disable C1
		// LED1 ON

	// Disable C1
	// Enable C2	
	// Setting C2
	// Read Camera C2
	// Write to SDCard						// Or write to SDRAM first then write to sdcard
	// When Finished
		// Disable C2
		// LED2 ON

	// Test Buzz
	/* Infinite loop */
	while (1)
	{
		HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_2);
		HAL_Delay(1000);
		//writeTFCard(&fatfs,SD_Path);
		//writeTFCard(SD_Path);
	}
			
	/* USER CODE END 3 */

}

void i2cWrite(uint8_t I2C_ADDRESS, uint8_t *aTxBuffer, uint8_t TXBUFFERSIZE) 
{	
		/* -> Start the transmission process */
		/* While the I2C in reception process, user can transmit data through "aTxBuffer" buffer */
		while(HAL_I2C_Master_Transmit(&hi2c2, (uint16_t)I2C_ADDRESS<<1, (uint8_t*)aTxBuffer, (uint16_t)TXBUFFERSIZE, (uint32_t)DEFTIMEOUT)!= HAL_OK)
		{
				if (HAL_I2C_GetError(&hi2c2) != HAL_I2C_ERROR_AF)
				{
						Debug("EW");
						break;
				}
		}

		/* -> Wait for the end of the transfer */
		/* Before starting a new communication transfer, you need to check the current
		 * state of the peripheral; if it’s busy you need to wait for the end of current
		 * transfer before starting a new one.
		 * For simplicity reasons, this example is just waiting till the end of the
		 * transfer, but application may perform other tasks while transfer operation
		 * is ongoing.
		 */
			while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY)
			{
			}
}
void i2cRead(uint8_t I2C_ADDRESS, uint8_t RegAddr, uint8_t *aRxBuffer, uint8_t RXBUFFERSIZE)
{
		/* -> Lets ask for register's address */
		i2cWrite(I2C_ADDRESS, &RegAddr, 1);

		/* -> Put I2C peripheral in reception process */
		while(HAL_I2C_Master_Receive(&hi2c2, (uint16_t)I2C_ADDRESS<<1, aRxBuffer, (uint16_t)RXBUFFERSIZE, (uint32_t)DEFTIMEOUT) != HAL_OK)
		{
				/* Error_Handler() function is called when Timeout error occurs.
				 * When Acknowledge failure occurs (Slave don't acknowledge it's address)
				 * Master restarts communication
				 */
				if (HAL_I2C_GetError(&hi2c2) != HAL_I2C_ERROR_AF)
				{
						Debug("ER");
						break;
				}
		}

		/* -> Wait for the end of the transfer */
		/* Before starting a new communication transfer, you need to check the current
		 * state of the peripheral; if it’s busy you need to wait for the end of current
		 * transfer before starting a new one.
		 * For simplicity reasons, this example is just waiting till the end of the
		 * transfer, but application may perform other tasks while transfer operation
		 * is ongoing.
		 **/
		while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY)
		{
		}
}
void Debug(char *msg)
{
	uartWrite("Debug: ");
	uartWrite(msg);
	uartWrite("\r\n");
}
void uartWrite(void *data)
{
	HAL_UART_Transmit(&huart4,(uint8_t *)data,(uint16_t)strlen(data),(uint32_t)DEFTIMEOUT);
}

/**
	* @brief	Perform the SDRAM exernal memory inialization sequence
	* @param	hsdram: SDRAM handle
	* @param	Command: Pointer to SDRAM command structure
	* @retval None
	*/
static void SDRAM_Initialization_Sequence(FMC_SDRAM_CommandTypeDef *Command)
{
	__IO uint32_t tmpmrd =0;
	/* Step 3:	Configure a clock configuration enable command */
	Command->CommandMode 			 = FMC_SDRAM_CMD_CLK_ENABLE;
	Command->CommandTarget 		 = FMC_SDRAM_CMD_TARGET_BANK2;
	Command->AutoRefreshNumber 	 = 1;
	Command->ModeRegisterDefinition = 0;

	/* Send the command */
	HAL_SDRAM_SendCommand(&hsdram1, Command, 0x1000);

	/* Step 4: Insert 100 ms delay */
	HAL_Delay(100);
		
	/* Step 5: Configure a PALL (precharge all) command */ 
	Command->CommandMode 			 = FMC_SDRAM_CMD_PALL;
	Command->CommandTarget 			 = FMC_SDRAM_CMD_TARGET_BANK2;
	Command->AutoRefreshNumber 	 = 1;
	Command->ModeRegisterDefinition = 0;

	/* Send the command */
	HAL_SDRAM_SendCommand(&hsdram1, Command, 0x1000);	
	
	/* Step 6 : Configure a Auto-Refresh command */ 
	Command->CommandMode 			 = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
	Command->CommandTarget 		 = FMC_SDRAM_CMD_TARGET_BANK2;
	Command->AutoRefreshNumber 	 = 4;
	Command->ModeRegisterDefinition = 0;

	/* Send the command */
	HAL_SDRAM_SendCommand(&hsdram1, Command, 0x1000);
	
	/* Step 7: Program the external memory mode register */
	tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2					|
										 SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL	 |
										 SDRAM_MODEREG_CAS_LATENCY_3					 |
										 SDRAM_MODEREG_OPERATING_MODE_STANDARD |
										 SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
	
	Command->CommandMode 				= FMC_SDRAM_CMD_LOAD_MODE;
	Command->CommandTarget 		 	= FMC_SDRAM_CMD_TARGET_BANK2;
	Command->AutoRefreshNumber 	 = 1;
	Command->ModeRegisterDefinition = tmpmrd;

	/* Send the command */
	HAL_SDRAM_SendCommand(&hsdram1, Command, 0x1000);
	
	/* Step 8: Set the refresh rate counter */
	/* (15.62 us x Freq) - 20 */

	/* Set the device refresh counter */
	HAL_SDRAM_ProgramRefreshRate(&hsdram1, REFRESH_COUNT); 
}
/* FMC initialization function */
void MX_FMC_Init(void)
{
	FMC_SDRAM_TimingTypeDef SdramTiming;

	/** Perform the SDRAM1 memory initialization sequence
	*/
	hsdram1.Instance = FMC_SDRAM_DEVICE;
	/* hsdram1.Init */
	hsdram1.Init.SDBank = FMC_SDRAM_BANK2;
	/* Column addressing: [8:0] */
	hsdram1.Init.ColumnBitsNumber 	= FMC_SDRAM_COLUMN_BITS_NUM_8;
	/* Row addressing: [12:0] */
	hsdram1.Init.RowBitsNumber 			= FMC_SDRAM_ROW_BITS_NUM_12;
	hsdram1.Init.MemoryDataWidth 		= FMC_SDRAM_MEM_BUS_WIDTH_16;
	hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
	hsdram1.Init.CASLatency 				= FMC_SDRAM_CAS_LATENCY_3;
	hsdram1.Init.WriteProtection		= FMC_SDRAM_WRITE_PROTECTION_DISABLE;
	hsdram1.Init.SDClockPeriod			= FMC_SDRAM_CLOCK_PERIOD_3;
	hsdram1.Init.ReadBurst					= FMC_SDRAM_RBURST_DISABLE;
	hsdram1.Init.ReadPipeDelay			= FMC_SDRAM_RPIPE_DELAY_1;
	/* SdramTiming */
//	SdramTiming.LoadToActiveDelay = 16;
//	SdramTiming.ExitSelfRefreshDelay = 16;
//	SdramTiming.SelfRefreshTime = 16;
//	SdramTiming.RowCycleDelay = 16;
//	SdramTiming.WriteRecoveryTime = 16;
//	SdramTiming.RPDelay = 16;
//	SdramTiming.RCDDelay = 16;
	/* Timing configuration for 84 Mhz of SD clock frequency (168Mhz/2) 
	*		168MHz/2 = 84Mhz
	*/
	/* TMRD: 2 Clock cycles 1/84Mhz = 11.9ns*/
	SdramTiming.LoadToActiveDelay		= 2;
	/* TXSR: min=70ns (6x11.90ns) */
	SdramTiming.ExitSelfRefreshDelay = 7;
	/* TRAS: min=42ns (4x11.90ns) max=120k (ns) */
	SdramTiming.SelfRefreshTime			= 4;
	/* TRC:	min=63 (6x11.90ns) */				
	SdramTiming.RowCycleDelay				= 7;
	/* TWR:	2 Clock cycles */
	SdramTiming.WriteRecoveryTime		= 4;
	/* TRP:	15ns => 2x11.90ns */
	SdramTiming.RPDelay							= 2;
	/* TRCD: 15ns => 2x11.90ns */
	SdramTiming.RCDDelay						 = 2;

	if(HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
	{
		/* Initialization Error */
			Debug("Err init fmc");
	}
	SDRAM_Initialization_Sequence(&sdramCommand);
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{

	RCC_ClkInitTypeDef RCC_ClkInitStruct;
	RCC_OscInitTypeDef RCC_OscInitStruct;

	__PWR_CLK_ENABLE();

	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
	RCC_OscInitStruct.PLL.PLLM = 8;
	RCC_OscInitStruct.PLL.PLLN = 336;
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
	RCC_OscInitStruct.PLL.PLLQ = 7;
	HAL_RCC_OscConfig(&RCC_OscInitStruct);

	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
															|RCC_CLOCKTYPE_PCLK2;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;
	HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

}

/* ADC1 init function */
void MX_ADC1_Init(void)
{

	ADC_ChannelConfTypeDef sConfig;

		/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
		*/
	hadc1.Instance = ADC1;
	hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
	hadc1.Init.Resolution = ADC_RESOLUTION12b;
	hadc1.Init.ScanConvMode = DISABLE;
	hadc1.Init.ContinuousConvMode = DISABLE;
	hadc1.Init.DiscontinuousConvMode = DISABLE;
	hadc1.Init.NbrOfDiscConversion = 1;
	hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
	hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
	hadc1.Init.NbrOfConversion = 1;
	hadc1.Init.DMAContinuousRequests = DISABLE;
	hadc1.Init.EOCSelection = EOC_SINGLE_CONV;
	HAL_ADC_Init(&hadc1);

		/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 
		*/
	sConfig.Channel = ADC_CHANNEL_12;
	sConfig.Rank = 1;
	sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
	HAL_ADC_ConfigChannel(&hadc1, &sConfig);

}

/* ADC2 init function */
void MX_ADC2_Init(void)
{

	ADC_ChannelConfTypeDef sConfig;

		/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
		*/
	hadc2.Instance = ADC2;
	hadc2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
	hadc2.Init.Resolution = ADC_RESOLUTION12b;
	hadc2.Init.ScanConvMode = DISABLE;
	hadc2.Init.ContinuousConvMode = DISABLE;
	hadc2.Init.DiscontinuousConvMode = DISABLE;
	hadc2.Init.NbrOfDiscConversion = 1;
	hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
	hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
	hadc2.Init.NbrOfConversion = 1;
	hadc2.Init.DMAContinuousRequests = DISABLE;
	hadc2.Init.EOCSelection = EOC_SINGLE_CONV;
	HAL_ADC_Init(&hadc2);

		/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 
		*/
	sConfig.Channel = ADC_CHANNEL_13;
	sConfig.Rank = 1;
	sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
	HAL_ADC_ConfigChannel(&hadc2, &sConfig);

}

/* DAC init function */
void MX_DAC_Init(void)
{

	DAC_ChannelConfTypeDef sConfig;

		/**DAC Initialization 
		*/
	hdac.Instance = DAC;
	HAL_DAC_Init(&hdac);

		/**DAC channel OUT2 config 
		*/
	sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
	sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
	HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_2);

}

/* DCMI init function */
void MX_DCMI_Init(void)
{

	hdcmi.Instance = DCMI;
	hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
	hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING;
	hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW;
	hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;
	hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
	hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
	hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;
	HAL_DCMI_Init(&hdcmi);

}

/* I2C2 init function */
void MX_I2C2_Init(void)
{

	hi2c2.Instance = I2C2;
	hi2c2.Init.ClockSpeed = 300000;
	hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
	hi2c2.Init.OwnAddress1 = 0;
	hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
	hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
	hi2c2.Init.OwnAddress2 = 0;
	hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
	hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
	HAL_I2C_Init(&hi2c2);

}

/* SDIO init function */
void MX_SDIO_SD_Init(void)
{

	hsd.Instance = SDIO;
	hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
	hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
	hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
	hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
	hsd.Init.ClockDiv = 0;
	HAL_SD_Init(&hsd, &SDCardInfo);

}

/* SPI5 init function */
void MX_SPI5_Init(void)
{

	hspi5.Instance = SPI5;
	hspi5.Init.Mode = SPI_MODE_MASTER;
	hspi5.Init.Direction = SPI_DIRECTION_2LINES;
	hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
	hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
	hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
	hspi5.Init.NSS = SPI_NSS_SOFT;
	hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
	hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
	hspi5.Init.TIMode = SPI_TIMODE_DISABLED;
	hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
	HAL_SPI_Init(&hspi5);	

}

/* UART4 init function */
void MX_UART4_Init(void)
{

	huart4.Instance = UART4;
	huart4.Init.BaudRate = 115200;
	huart4.Init.WordLength = UART_WORDLENGTH_8B;
	huart4.Init.StopBits = UART_STOPBITS_1;
	huart4.Init.Parity = UART_PARITY_NONE;
	huart4.Init.Mode = UART_MODE_TX_RX;
	huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart4.Init.OverSampling = UART_OVERSAMPLING_16;
	HAL_UART_Init(&huart4);

}


/** Configure pins as 
				* Analog 
				* Input 
				* Output
				* EVENT_OUT
				* EXTI
				* Free pins are configured automatically as Analog (this feature is enabled through 
				* the Code Generation settings)
		 PB4	 ------> S_TIM3_CH1
*/
void MX_GPIO_Init(void)
{

	GPIO_InitTypeDef GPIO_InitStruct;

	/* GPIO Ports Clock Enable */
	__GPIOE_CLK_ENABLE();
	__GPIOC_CLK_ENABLE();
	__GPIOF_CLK_ENABLE();
	__GPIOH_CLK_ENABLE();
	__GPIOA_CLK_ENABLE();
	__GPIOB_CLK_ENABLE();
	__GPIOG_CLK_ENABLE();
	__GPIOD_CLK_ENABLE();

	/*Configure GPIO pins : PE2 PE5 PE6 */
	GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_5|GPIO_PIN_6;
	GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

	/*Configure GPIO pin : PE3 */
	GPIO_InitStruct.Pin = GPIO_PIN_3;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLDOWN;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

	/*Configure GPIO pins : PC13 PC5 */
	GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_5;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

	/*Configure GPIO pins : PC14 PC15 PC6 PC7 */
	GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_6|GPIO_PIN_7;
	GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
	
		/*Configure GPIO pin : PF6 */
	GPIO_InitStruct.Pin = GPIO_PIN_6;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
	
	/*Configure GPIO pin : PF10 */
	GPIO_InitStruct.Pin = GPIO_PIN_10;
	GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

	/*Configure GPIO pin : PC1 */
	GPIO_InitStruct.Pin = GPIO_PIN_1;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

	/*Configure GPIO pins : PA2 PA3 */
	GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLDOWN;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	/*Configure GPIO pins : PA7 PA8 PA15 */
	GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_15;
	GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	/*Configure GPIO pin : PC4 */
	GPIO_InitStruct.Pin = GPIO_PIN_4;
	GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

	/*Configure GPIO pins : PB0 PB1 PB12 PB13 
													 PB14 PB15 */
	GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_12|GPIO_PIN_13 
													|GPIO_PIN_14|GPIO_PIN_15;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	/*Configure GPIO pin : PB2 */
	GPIO_InitStruct.Pin = GPIO_PIN_2;
	GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	/*Configure GPIO pins : PD11 PD12 PD13 */
	GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

	/*Configure GPIO pins : PG2 PG3 PG6 PG7 
													 PG9 PG12 PG14 */
	GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_6|GPIO_PIN_7 
													|GPIO_PIN_9|GPIO_PIN_12|GPIO_PIN_14;
	GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

	/*Configure GPIO pins : PD4 PD5 PD6 PD7 */
	GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
	GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

	/*Configure GPIO pin : PG13 */
	GPIO_InitStruct.Pin = GPIO_PIN_13;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

	/*Configure GPIO pin : PB4 */
	GPIO_InitStruct.Pin = GPIO_PIN_4;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

#ifdef USE_FULL_ASSERT

/**
	 * @brief Reports the name of the source file and the source line number
	 * where the assert_param error has occurred.
	 * @param file: pointer to the source file name
	 * @param line: assert_param error line source number
	 * @retval None
	 */
void assert_failed(uint8_t* file, uint32_t line)
{
	/* USER CODE BEGIN 6 */
	/* User can add his own implementation to report the file name and line number,
		ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
	/* USER CODE END 6 */

}

#endif

/**
	* @}
	*/ 

/**
	* @}
*/ 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
